import _thread as thread
import base64
import datetime
import hashlib
import hmac
import json
from urllib.parse import urlparse, urlencode
import ssl
from datetime import datetime
from time import mktime
from wsgiref.handlers import format_date_time
import websocket


class ImageUnderstanding:
    def __init__(self, image_path=None):
        # 固定参数（从控制台获取）
        self.appid = "c98c14d0"
        self.api_key = "c6e5483eb0a4e44ca4969b1a5f75da70"
        self.api_secret = "YzlhZTg1N2UyNzU0ODQ1NWJhMTAwNzFl"
        self.imageunderstanding_url = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image"

        # 默认简历图片路径
        self.image_path = image_path or "简历.png"

        # 读取图像数据
        with open(self.image_path, 'rb') as f:
            self.imagedata = f.read()

        # 初始化对话上下文
        self.text = [{
            "role": "user",
            "content": str(base64.b64encode(self.imagedata), 'utf-8'),
            "content_type": "image"
        }]

        self.answer = ""

    def create_url(self):
        host = urlparse(self.imageunderstanding_url).netloc
        path = urlparse(self.imageunderstanding_url).path

        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        signature_origin = f"host: {host}\n"
        signature_origin += f"date: {date}\n"
        signature_origin += f"GET {path} HTTP/1.1"

        signature_sha = hmac.new(
            self.api_secret.encode('utf-8'),
            signature_origin.encode('utf-8'),
            digestmod=hashlib.sha256
        ).digest()

        signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = f'api_key="{self.api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

        v = {
            "authorization": authorization,
            "date": date,
            "host": host
        }

        url = self.imageunderstanding_url + '?' + urlencode(v)
        return url

    def on_error(self, ws, error):
        print("### error:", error)

    def on_close(self, ws, one, two):
        print("Connection closed.")

    def on_open(self, ws):
        thread.start_new_thread(self.run, (ws,))

    def run(self, ws):
        data = json.dumps(self.gen_params(question=self.question))
        ws.send(data)

    def on_message(self, ws, message):
        data = json.loads(message)
        code = data['header']['code']
        if code != 0:
            print(f'请求错误: {code}, {data}')
            ws.close()
        else:
            choices = data["payload"]["choices"]
            status = choices["status"]
            content = choices["text"][0]["content"].replace("*", "")
            print(content, end="")
            self.answer += content

            if status == 2:
                ws.close()

    def gen_params(self, appid=None, question=None):
        if appid is None:
            appid = self.appid

        data = {
            "header": {
                "app_id": appid
            },
            "parameter": {
                "chat": {
                    "domain": "imagev3",
                    "temperature": 0.5,
                    "top_k": 4,
                    "max_tokens": 200,
                    "auditing": "default"
                }
            },
            "payload": {
                "message": {
                    "text": question
                }
            }
        }

        return data

    def get_text(self, role, content):
        jsoncon = {}
        jsoncon["role"] = role
        jsoncon["content"] = content
        self.text.append(jsoncon)
        return self.text

    def get_length(self, text):
        length = 0
        for content in text:
            temp = content["content"]
            length += len(temp)
        return length

    def check_len(self, text):
        while self.get_length(text[1:]) > 8000:
            del text[1]
        return text

    def analyze_resume(self, input_question="帮我分析一下这份简历的不足之处，并按照满分是一百分并进行打分,先进行打分再分析"):
        self.question = self.check_len(self.get_text("user", input_question))
        ws_url = self.create_url()

        ws = websocket.WebSocketApp(
            ws_url,
            on_message=self.on_message,
            on_error=self.on_error,
            on_close=self.on_close,
            on_open=self.on_open
        )
        ws.appid = self.appid
        ws.question = self.question
        ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

        self.get_text("assistant", self.answer)
        return self.answer


# 示例使用
'''
if __name__ == '__main__':
    analyzer = ImageUnderstanding()  # 使用默认配置和图片路径
    result = analyzer.analyze_resume()
    print("\n最终分析结果：\n", result)
'''
